package com.cskaoyan.javase.oop1._11static._5exercise;

/**
 * 读程序题
 * 类加载的连环触发
 *
 * @since 11:16
 * @author wuguidong@cskaoyan.onaliyun.com
 */

public class Demo {
    /*
        静态成员变量的显式赋值需要在类加载过程中执行
        这个静态成员变量是引用数据类型
        这里需要创建对象

        于是创建Cat对象需要类加载Cat
        在类加载Demo的过程中,转而进行类加载Cat
        类加载完Cat后,完成创建Cat对象,才能完成Demo类的类加载

        Demo类最早开始类加载,但是最后完成类加载
     */
    static Cat cat = new Cat();
    // static Cat cat;

    /*
        成员变量的显式赋值
        需要在构造器执行时,在构造器之前执行
     */
    Dog dog = new Dog();
    /*
        以下静态成员和成员变量
        没有显式赋值
        不会被执行,只有默认值
     */
    Dog dog2;
    static Dog dog3;

    // 不要忘记启动main方法,触发该类的类加载
    // 类加载过程中需要完成静态成员变量的初始化和赋值
    public static void main(String[] args) {
        System.out.println("hello world!");
        Demo d = new Demo();
    }

    public Demo() {
        System.out.println("demo");
    }
}

class Cat {
    /*
        类加载Cat
        需要完成静态成员变量的显式赋值
        需要创建Dog对象
        于是又需要类加载Dog
        在类加载Cat的过程中,转而进行类加载Dog
        类加载完Dog后,完成创建Dog对象,才能完成Cat类的类加载
     */
    static Dog dog = new Dog();

    public Cat() {
        System.out.println("cat");
    }
}

class Dog {
    /*
        Dog类当中没有static声明
        直接类加载结束,类加载对程序的运行没有影响

        Dog类最后开始类加载,最先完成类加载
        这个过程仍然利用方法栈帧先进后出的特点完成
     */
    // static int num = 10;

    /*
        这里要想完成Dog类的类加载
        假如需要创建Demo类对象
        可以不可以呢?

        可以,原因下午再讲.
     */
    static Demo demo = new Demo();

    public Dog() {
        System.out.println("dog");
    }
}